home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / amiga.free / sorgenti vari / wolfedit2 2.0.4 source.sit / WolfEdit2 2.0.4 Source / UMultiArt.p < prev    next >
Text File  |  1996-06-14  |  13KB  |  564 lines

  1. unit UMultiArt;
  2.  
  3. interface
  4.     uses
  5.         UWolfDoc;
  6.  
  7.     type
  8.  
  9.         MultiArtType = (bjArt, faceArt320, faceArt512, faceArt640);
  10.  
  11.     procedure EditMultiArt (doc: TMapListDoc; which: MultiArtType);
  12.  
  13. implementation
  14.     uses
  15.         UList, UXWindow, UScrap, UPixMapView, ULZSS, UCTables, UMemory;
  16.  
  17.     const
  18.  
  19.         maxMAImages = 60;
  20.         multiArtWindID = 134;
  21.         bjImageNamesID = 128;
  22.         faceImageNamesID = 129;
  23.         outOfMemAlrtID = 148;
  24.  
  25.     type
  26.  
  27.         LongintPtr = ^longint;
  28.         MAIndexArray = array[1..maxMAImages] of longint;
  29.         MAIndexPtr = ^MAIndexArray;
  30.  
  31.         PairPtr = ^Pair;
  32.         Pair = record
  33.                 x, y: integer;
  34.             end;
  35.  
  36.         MAImageRecord = record
  37.                 frame: Rect;
  38.                 bounds: Rect;
  39.                 masked: boolean;
  40.                 data: Handle;
  41.             end;
  42.  
  43.         TMultiArtWindow = object(TXWindow)
  44.                 fType: MultiArtType;
  45.                 fMapList: TMapListDoc;
  46.                 fNumImages: integer;
  47.                 fImages: array[1..maxMAImages] of MAImageRecord;
  48.                 fChanged: boolean;
  49.                 fCurrentImage: integer;
  50.                 fMAList: TMAList;
  51.                 fImageView: TPixMapView;
  52.                 fCTab: CTabHandle;
  53.                 fIntermissionCTab: CTabHandle;
  54.                 fSizeView: TMASizeView;
  55.                 procedure IMultiArtWindow (itsDoc: TMapListDoc; itsType: MultiArtType);
  56.                 procedure Free;
  57.                 override;
  58.                 procedure SetupMenus;
  59.                 override;
  60.                 procedure DoMenuCommand (cmdNumber: integer);
  61.                 override;
  62.                 procedure DoCopy;
  63.                 procedure DoPaste;
  64.                 procedure InstallBrgr (brgr: Handle);
  65.                 procedure SelectImage (n: integer);
  66.                 procedure ShowImage;
  67.                 procedure FlushImage;
  68.                 procedure HideImage;
  69.                 function Changed: boolean;
  70.                 override;
  71.                 function Flush: boolean;
  72.                 override;
  73.                 procedure UpdateTitle;
  74.                 override;
  75.             end;
  76.  
  77.         TMAList = object(TList)
  78.                 fMAWindow: TMultiArtWindow;
  79.                 procedure DrawCell (cell: Point; r: Rect; var hilite: boolean);
  80.                 override;
  81.                 procedure SetSelectionRect (newSel: Rect);
  82.                 override;
  83.             end;
  84.  
  85.         TMASizeView = object(TView)
  86.                 fMAWindow: TMultiArtWindow;
  87.                 procedure IMASizeView (itsWin: TMultiArtWindow);
  88.                 procedure Draw;
  89.                 override;
  90.             end;
  91.  
  92.     procedure OutOfMemory;
  93.     begin
  94.         DoAlert(outOfMemAlrtID);
  95.     end;
  96.  
  97.     function GetMABrgrID (artType: MultiArtType): integer;
  98.     begin
  99.         GetMABrgrID := 141 + ord(artType);
  100.     end;
  101.  
  102.     function GetMACTabID (itsType: MultiArtType): integer;
  103.     begin
  104.         if itsType = bjArt then
  105.             GetMACTabID := intermissionCTabID
  106.         else
  107.             GetMACTabID := gameCTabID;
  108.     end;
  109.  
  110.     function GetNumImages (artType: MultiArtType): integer;
  111.     begin
  112.         case artType of
  113.             bjArt: 
  114.                 GetNumImages := 3;
  115.             faceArt512: 
  116.                 GetNumImages := 57;
  117.             otherwise
  118.                 GetNumImages := 47;
  119.         end;
  120.     end;
  121.  
  122.     procedure GetImageName (artType: MultiArtType; i: integer; var s: Str255);
  123.         var
  124.             id: integer;
  125.     begin
  126.         case artType of
  127.             bjArt: 
  128.                 id := bjImageNamesID;
  129.             otherwise
  130.                 id := faceImageNamesID;
  131.         end;
  132.         GetIndString(s, id, i);
  133.     end;
  134.  
  135.     function ImageHasMask (itsType: MultiArtType; i: integer): boolean;
  136.     begin
  137.         if itsType = bjArt then
  138.             ImageHasMask := false
  139.         else
  140.             case i of
  141.                 13..36: 
  142.                     ImageHasMask := true;
  143.                 otherwise
  144.                     ImageHasMask := false;
  145.             end;
  146.     end;
  147.  
  148.     procedure SetImageFrame (var frame: Rect; artType: MultiArtType; masked: boolean; dim: Pair);
  149.     begin
  150.         if masked then
  151.             case artType of
  152.                 faceArt320: 
  153.                     SetRect(frame, 0, 0, 64, 64);
  154.                 faceArt512: 
  155.                     SetRect(frame, 0, 0, 102, 102);
  156.                 faceArt640: 
  157.                     SetRect(frame, 0, 0, 128, 128);
  158.             end
  159.         else
  160.             SetRect(frame, 0, 0, dim.x, dim.y);
  161.     end;
  162.  
  163.     procedure TMAList.DrawCell (cell: Point; r: Rect; var hilite: boolean);
  164.         var
  165.             name: Str255;
  166.     begin
  167.         TextFont(geneva);
  168.         TextSize(9);
  169.         if hilite then begin
  170.                 FillRect(r, black);
  171.                 TextMode(srcBic);
  172.             end
  173.         else begin
  174.                 EraseRect(r);
  175.                 TextMode(srcOr);
  176.             end;
  177.         MoveTo(r.left + 5, r.bottom - 3);
  178.         GetImageName(fMAWindow.fType, cell.v + 1, name);
  179.         DrawString(name);
  180.         hilite := false;
  181.     end;
  182.  
  183.     procedure TMAList.SetSelectionRect (newSel: Rect);
  184.     begin
  185.         inherited SetSelectionRect(newSel);
  186.         fMAWindow.SelectImage(fSelection.bottom);
  187.     end;
  188.  
  189.     procedure TMASizeView.IMASizeView (itsWin: TMultiArtWindow);
  190.         var
  191.             r: Rect;
  192.     begin
  193.         SetRect(r, 0, 0, 300, 16);
  194.         IView(nil, nil, r);
  195.         fMAWindow := itsWin;
  196.     end;
  197.  
  198.     procedure TMASizeView.Draw;
  199.     begin
  200.         EraseRect(fExtent);
  201.         with fMAWindow do begin
  202.                 if fCurrentImage > 0 then begin
  203.                         TextFont(geneva);
  204.                         TextSize(9);
  205.                         MoveTo(0, fExtent.bottom - 4);
  206.                         with fImages[fCurrentImage] do begin
  207.                                 WriteDraw('Size: ', bounds.right - bounds.left : 1, 'x', bounds.bottom - bounds.top : 1);
  208.                                 if masked then
  209.                                     WriteDraw(' (max ', frame.right : 1, 'x', frame.bottom : 1, ')');
  210.                                 if masked then
  211.                                     WriteDraw('  Offset: ', bounds.left - frame.left : 1, ',', bounds.top - frame.top : 1);
  212.                             end;
  213.                     end;
  214.             end;
  215.     end;
  216.  
  217.     procedure TMultiArtWindow.IMultiArtWindow (itsDoc: TMapListDoc; itsType: MultiArtType);
  218.         var
  219.             brgrID: integer;
  220.             brgr: Handle;
  221.             cTabID: integer;
  222.             maList: TMAList;
  223.             sizeView: TMASizeView;
  224.     begin
  225.         fType := itsType;
  226.         fMapList := itsDoc;
  227.         IGetNewCWindow(itsDoc, multiArtWindID, [wCloseOnGoAway]);
  228.         fNumImages := GetNumImages(fType);
  229.         fChanged := false;
  230.         fImageView := nil;
  231.         cTabID := GetMACTabID(fType);
  232.         fCTab := GetMapListCTab(itsDoc, cTabID);
  233.         fIntermissionCTab := GetMapListCTab(itsDoc, intermissionCTabID);
  234.         new(maList);
  235.         maList.IList(150, 12, 1, fNumImages, 0, []);
  236.         fMAList := maList;
  237.         fMAList.fMAWindow := self;
  238.         Place(fMAList, nil, nil, 10, 10, natural, 300, [frmBorder, frmVScroll]);
  239.         fMAList.fFrame.fLineSize.v := 12;
  240.         new(sizeView);
  241.         sizeView.IMASizeView(self);
  242.         fSizeView := sizeView;
  243.         Place(fSizeView, fMAList, nil, 25, 10, natural, natural, []);
  244.         brgrID := GetMABrgrID(fType);
  245.         brgr := fMapList.GetMiscBrgr(brgrID);
  246.         if brgr = nil then
  247.             brgr := GetResource('BRGR', brgrID);
  248.         InstallBrgr(brgr);
  249.     end;
  250.  
  251.     procedure TMultiArtWindow.Free;
  252.         var
  253.             i: integer;
  254.     begin
  255.         for i := 1 to fNumImages do begin
  256. {writeln('TMultiArtWindow.Free: DisposHandle(fImages[i].data)', GetHandleSize(fImages[i].data));    {***}
  257.                 DisposHandle(fImages[i].data);
  258.             end;
  259. {writeln('TMultiArtWindow.Free: DisposHandle(fCTab)', GetHandleSize(Handle(fCTab)));}
  260.         DisposHandle(Handle(fCTab));
  261. {writeln('TMultiArtWindow.Free: DisposHandle(fIntermissionCTab)', GetHandleSize(Handle(fIntermissionCTab)));}
  262.         DisposHandle(Handle(fIntermissionCTab));
  263.         inherited Free;
  264.     end;
  265.  
  266.     procedure TMultiArtWindow.SetupMenus;
  267.     begin
  268.         inherited SetupMenus;
  269.         if fCurrentImage > 0 then begin
  270.                 EnableCmd(copyCmd);
  271.                 if ProbeScrap('PICT') then
  272.                     EnableCmd(pasteCmd);
  273.             end;
  274.     end;
  275.  
  276.     procedure TMultiArtWindow.DoMenuCommand (cmdNumber: integer);
  277.     begin
  278.         case cmdNumber of
  279.             copyCmd: 
  280.                 DoCopy;
  281.             pasteCmd: 
  282.                 DoPaste;
  283.             otherwise
  284.                 inherited DoMenuCommand(cmdNumber);
  285.         end;
  286.     end;
  287.  
  288.     procedure TMultiArtWindow.DoCopy;
  289.     begin
  290.         fImageView.DoCopy;
  291.     end;
  292.  
  293.     procedure TMultiArtWindow.DoPaste;
  294.         var
  295.             pict: PicHandle;
  296.             width, height: longint;
  297.     begin
  298.         ReadScrap('PICT', pict);
  299.         if pict <> nil then begin
  300.                 with pict^^.picFrame do begin
  301.                         width := right - left;
  302.                         height := bottom - top;
  303.                     end;
  304.                 DisposHandle(Handle(pict));
  305.                 SetHandleSize(fImages[fCurrentImage].data, width * height);
  306.                 if MemError <> noErr then begin
  307.                         OutOfMemory;
  308.                         exit(DoPaste);
  309.                     end;
  310.                 HideImage;
  311.                 with fImages[fCurrentImage] do begin
  312.                         SetRect(bounds, 0, 0, width, height);
  313.                         if masked then
  314.                             OffsetRect(bounds, (frame.right - width) div 2, frame.bottom - height)
  315.                         else
  316.                             frame := bounds;
  317.                     end;
  318.                 ShowImage;
  319.                 fImageView.DoPaste;
  320.                 fChanged := true;
  321.                 fMapList.Changed;
  322.             end;
  323.     end;
  324.  
  325.     procedure TMultiArtWindow.InstallBrgr (brgr: Handle);
  326.         var
  327.             bufSize, dataSize: longint;
  328.             src, buf, p: Ptr;
  329.             index: MAIndexPtr;
  330.             dim, offset: Pair;
  331.             i: integer;
  332.             hasMask: boolean;
  333.             data: Handle;
  334.     begin
  335.         HLock(brgr);
  336.         bufSize := LongintPtr(brgr^)^;
  337. {writeln('TMultiArtWindow.InstallBrgr: NewPtr', bufSize);    {***}
  338.         buf := NewPtr(bufSize);
  339.         src := Ptr(ord(brgr^) + 4);
  340.         DLZSS(src, buf, bufSize);
  341.         HUnlock(brgr);
  342.         index := MAIndexPtr(buf);
  343.         for i := 1 to fNumImages do begin
  344.                 p := Ptr(ord(buf) + index^[i]);
  345.                 hasMask := ImageHasMask(fType, i);
  346.                 if hasMask then begin
  347.                         offset := PairPtr(p)^;
  348.                         p := Ptr(ord(p) + 4);
  349.                     end;
  350.                 dim := PairPtr(p)^;
  351.                 p := Ptr(ord(p) + 4);
  352.                 if not hasMask then begin
  353.                         offset.x := 0;
  354.                         offset.y := 0;
  355.                     end;
  356.  {$IFC FALSE}
  357.                 write(i, index^[i], dim.x : 1, '*', dim.y : 1);
  358.                 if hasMask then
  359.                     write('+', offset.x : 1, ',', offset.y : 1);
  360.                 writeln;
  361.  {$ENDC}
  362.                 dataSize := longint(dim.x) * longint(dim.y);
  363.                 data := NewHandle(dataSize);
  364. {writeln('TMultiArtWindow.InstallBrgr: NewHandle', dataSize);    {***}
  365.                 BlockMove(Ptr(p), data^, dataSize);
  366.                 with fImages[i] do begin
  367.                         masked := hasMask;
  368.                         SetImageFrame(frame, fType, masked, dim);
  369.                         SetRect(bounds, offset.x, offset.y, offset.x + dim.x, offset.y + dim.y);
  370.                     end;
  371.                 fImages[i].data := data;
  372.             end;
  373.         DisposPtr(buf);
  374.     end;
  375.  
  376.     function TMultiArtWindow.Changed: boolean;
  377.     begin
  378.         Changed := fChanged;
  379.     end;
  380.  
  381.     function TMultiArtWindow.Flush: boolean;
  382.         var
  383.             bufSize, dataSize: longint;
  384.             i: integer;
  385.             buf, p, q: Ptr;
  386.             index: MAIndexPtr;
  387.             brgr: Handle;
  388.             dim, offset: Pair;
  389.  
  390.         procedure Abort;
  391.         begin
  392.             DisposPtr(buf);
  393.             Flush := false;
  394.             exit(Flush);
  395.         end;
  396.  
  397. {$D-}
  398.         procedure PutMask;
  399.         begin
  400.             while dataSize > 0 do begin
  401.                     if q^ = 0 then
  402.                         p^ := -1
  403.                     else
  404.                         p^ := 0;
  405.                     p := Ptr(ord(p) + 1);
  406.                     q := Ptr(ord(q) + 1);
  407.                     dataSize := dataSize - 1;
  408.                 end;
  409.         end;
  410. {$D+}
  411.  
  412.     begin {TMultiArtWindow.Flush}
  413.         buf := nil;
  414.         if fChanged then begin
  415.                 FlushImage;
  416.                 bufSize := 0;
  417.                 for i := 1 to fNumImages do
  418.                     with fImages[i] do begin
  419.                             bufSize := bufSize + 8; {index entry + dimensions}
  420.                             if masked then
  421.                                 bufSize := bufSize + 4; {offset}
  422.                             dataSize := GetHandleSize(data);
  423.                             if masked then
  424.                                 dataSize := dataSize * 2;
  425.                             bufSize := bufSize + dataSize;
  426.                         end;
  427.                 buf := NewPtr(bufSize);
  428. {writeln('TMultiArtWindow.Flush: NewPtr', bufSize);    {***}
  429.                 if buf = nil then begin
  430.                         OutOfMemory;
  431.                         Abort;
  432.                     end;
  433.                 index := MAIndexPtr(buf);
  434.                 p := Ptr(ord(buf) + 4 * fNumImages);
  435.                 for i := 1 to fNumImages do begin
  436.                         index^[i] := ord(p) - ord(buf);
  437.                         with fImages[i] do begin
  438.                                 dim.x := bounds.right - bounds.left;
  439.                                 dim.y := bounds.bottom - bounds.top;
  440.                                 offset.x := bounds.left - frame.left;
  441.                                 offset.y := bounds.top - frame.top;
  442.                                 if masked then begin
  443.                                         PairPtr(p)^ := offset;
  444.                                         p := Ptr(ord(p) + 4);
  445.                                     end;
  446.                                 PairPtr(p)^ := dim;
  447.                                 p := Ptr(ord(p) + 4);
  448.                                 dataSize := GetHandleSize(data);
  449.                                 BlockMove(data^, p, dataSize);
  450.                                 p := Ptr(ord(p) + dataSize);
  451.                                 if masked then begin
  452.                                         q := data^;
  453.                                         PutMask;
  454.                                     end;
  455.                             end;
  456.                     end;
  457.                 brgr := LZSSX(4, nil, 0, buf, bufSize, false);
  458.                 if brgr = nil then
  459.                     Abort;
  460.                 LongintPtr(brgr^)^ := bufSize;
  461. {writeln('TMultiArtWindow.Flush: DisposPtr(buf)', GetHandleSize(buf));    {***}
  462.                 DisposPtr(buf);
  463.                 fMapList.InstallMiscBrgr(brgr, GetMABrgrID(fType));
  464.                 fChanged := false;
  465.             end; {if fChanged}
  466.         Flush := true;
  467.     end; {TMultiArtWindow.Flush}
  468.  
  469.     procedure TMultiArtWindow.SelectImage (n: integer);
  470.     begin
  471.         if n <> fCurrentImage then begin
  472.                 HideImage;
  473.                 fCurrentImage := n;
  474.                 ShowImage;
  475.                 fSizeView.Invalidate;
  476.             end;
  477.     end;
  478.  
  479.     procedure TMultiArtWindow.ShowImage;
  480.         var
  481.             pixels: Ptr;
  482.             i: integer;
  483.             imageView: TPixMapView;
  484.             cTab: CTabHandle;
  485.     begin
  486.         if fCurrentImage > 0 then begin
  487.                 i := fCurrentImage;
  488.                 if i > 47 then
  489.                     cTab := fIntermissionCTab
  490.                 else
  491.                     cTab := fCTab;
  492.                 new(imageView);
  493.                 imageView.IPixMapViewX(fImages[i].frame, fImages[i].bounds, cTab);
  494.                 fImageView := imageView;
  495.                 pixels := GetPixBaseAddr(fImageView.fPixMap);
  496.                 BlockMove(fImages[i].data^, pixels, GetHandleSize(fImages[i].data));
  497.                 Place(fImageView, fMAList, fSizeView, 25, 10, natural, natural, [frmBorder]);
  498.                 fImageView.fNextHandler := nil;
  499.             end;
  500.     end;
  501.  
  502.     procedure TMultiArtWindow.FlushImage;
  503.         var
  504.             pixels: Ptr;
  505.             i: integer;
  506.     begin
  507.         if (fImageView <> nil) & (fImageView.fChanged) then begin
  508.                 i := fCurrentImage;
  509.                 pixels := GetPixBaseAddr(fImageView.fPixMap);
  510.                 BlockMove(pixels, fImages[i].data^, GetHandleSize(fImages[i].data));
  511.                 fChanged := true;
  512.             end;
  513.     end;
  514.  
  515.     procedure TMultiArtWindow.HideImage;
  516.     begin
  517.         FlushImage;
  518.         if fImageView <> nil then begin
  519.                 fImageView.fFrame.Free;
  520.                 fImageView := nil;
  521.             end;
  522.     end;
  523.  
  524.     procedure TMultiArtWindow.UpdateTitle;
  525.         var
  526.             what: string;
  527.     begin
  528.         case fType of
  529.             bjArt: 
  530.                 what := 'Intermission Animation';
  531.             faceArt320: 
  532.                 what := 'Interface Art 320';
  533.             faceArt512: 
  534.                 what := 'Interface Art 512';
  535.             faceArt640: 
  536.                 what := 'Interface Art 640';
  537.         end;
  538.         SetTitle(concat(what, ' from ', fMapList.fFileName));
  539.     end;
  540.  
  541.     procedure EditMultiArt (doc: TMapListDoc; which: MultiArtType);
  542.         var
  543.             win: TWindow;
  544.             maWin: TMultiArtWindow;
  545.  
  546.         procedure TestWindow (win: TWindow);
  547.         begin
  548.             if member(win, TMultiArtWindow) then
  549.                 if TMultiArtWindow(win).fType = which then begin
  550.                         win.Select;
  551.                         exit(EditMultiArt);
  552.                     end;
  553.         end;
  554.  
  555.     begin {EditMultiArt}
  556.         doc.EachWindowDo(TestWindow);
  557.         if EnoughMemory($80000) then begin
  558.                 new(maWin);
  559.                 maWin.IMultiArtWindow(doc, which);
  560.                 maWin.Select;
  561.             end;
  562.     end;
  563.  
  564. end.